package com.getApiData;

import com.ssl.SslUtils;
import okhttp3.*;
import org.apache.commons.io.FileUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>根据url地址下载文件至指定目录</p>
 *
 * @author bcl
 */
public class GetUrlFile {

    private static InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 1080);

    private static Proxy proxy = new Proxy(Proxy.Type.HTTP, inetSocketAddress);

    /**
     * 从输入流中获取字节数组
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        if (bos != null) {
            bos.close();
        }
        return bos.toByteArray();
    }

    /**
     * <p>根据网路下载文件 返回Map 测试有效</p>
     *
     * @param urlStr   网络地址
     * @param fileName 文件名称
     * @param savePath 保存文件路径
     * @return
     */
    public static Map<String, Object> downLoadFromUrl(String urlStr, String savePath/*, String folderName*/, String fileName) throws Exception {

        URL url = new URL(urlStr);

        if ("https".equalsIgnoreCase(url.getProtocol())) {

            SslUtils.ignoreSsl();

        }
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        // 设置超时间为5秒
        conn.setConnectTimeout(5 * 1000);
        // 防止屏蔽程序抓取而出现403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        // 得到输入流
        InputStream inputStream = conn.getInputStream();
        // 获取自家数组
        byte[] getData = readInputStream(inputStream);
        // 文件保存位置  当指定文件夹不存在则创建
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdirs();
        }
        File file = new File(savePath, fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        if (fos != null) {
            fos.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }
        conn.disconnect();
        Map<String, Object> map = new HashMap<String, Object>();
        //map.put("filePath", saveDir + File.separator + fileName);
        map.put("url", "http://www.祁雪.cn/lse/images-LSE/" + fileName);
        map.put("code", "200");
        return map;
    }

    /**
     * <p>根据网路下载文件 返回Map 测试有效</p> 走代理
     *
     * @param urlStr   网络地址
     * @param fileName 文件名称
     * @param savePath 保存文件路径
     * @return
     */
    public static void downLoadFromUrlByProxy(String urlStr, String savePath/*, String folderName*/, String fileName) throws Exception {

        URL url = new URL(urlStr);

        if ("https".equalsIgnoreCase(url.getProtocol())) {

            SslUtils.ignoreSsl();

        }

        HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);

        // 设置超时间为5秒
        conn.setConnectTimeout(5 * 1000);
        // 防止屏蔽程序抓取而出现403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        // 得到输入流
        InputStream inputStream = conn.getInputStream();
        // 获取自家数组
        byte[] getData = readInputStream(inputStream);
        // 文件保存位置  当指定文件夹不存在则创建
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdirs();
        }
        File file = new File(savePath, fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        fos.flush();

        fos.close();
        inputStream.close();
        conn.disconnect();
    }

    /**
     * <p>从网络上下载文件  无返回参数  有效</p>
     *
     * @param url      网络地址
     * @param dir      文件保存地址
     * @param fileName 文件名
     * @throws Exception
     */
    public static void downLoadHttpUrl(String url, String dir, String fileName) throws Exception {
        URL httpUrl = new URL(url);
        if ("https".equalsIgnoreCase(httpUrl.getProtocol())) {

            SslUtils.ignoreSsl();

        }
        FileUtils.copyURLToFile(httpUrl, new File(dir, fileName));
    }

    /**
     * @param urlStr   网络地址
     * @param fileName 文件名称
     * @param savePath 保存文件路径
     * @return
     */
    public static void downLoadHttpUrlByProxy(String urlStr, String savePath/*, String folderName*/, String fileName) throws Exception {

        URL url = new URL(urlStr);

        if ("https".equalsIgnoreCase(url.getProtocol())) {

            SslUtils.ignoreSsl();

        }
        HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);

        // 设置超时间为5秒
        conn.setConnectTimeout(5 * 1000);
        // 防止屏蔽程序抓取而出现403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        // 得到输入流
        InputStream inputStream = conn.getInputStream();
        // 获取自家数组
        byte[] getData = readInputStream(inputStream);
        // 文件保存位置  当指定文件夹不存在则创建
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdirs();
        }
        File file = new File(savePath, fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        fos.flush();

        fos.close();
        inputStream.close();
        conn.disconnect();
    }

    /**
     * 生成安全套接字工厂，用于https请求的证书跳过
     *
     * @return
     */
    public SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }
        return ssfFactory;
    }

    /**
     * 用于信任所有证书
     */
    class TrustAllCerts implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    public static void main(String[] args) {
        // test
        try {
            String photoUrl = "http://fs.w.kugou.com/201808152241/fbb0ba652fb2c9c4b8c11760aa6dd5cc/G058/M03/19/07/HZQEAFcBT7KASSWvAEj7SyqZxt8253.mp3";   //文件URL地址


            String fileName = "test.mp3";     //为下载的文件命名

            String filePath = "f://test/";      //保存目录


            //System.out.println(file.getPath());
            //downLoadHttpUrl(photoUrl, filePath, fileName);
            Map<String, Object> map = downLoadFromUrl(photoUrl, fileName, filePath /*, ""*/);
            System.out.println(map.toString());
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
}
